package com.szholly.plug.arcgis.directive;

import static freemarker.template.ObjectWrapper.DEFAULT_WRAPPER;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Component;

import net.sf.json.JSONObject;

import com.szholly.plug.arcgis.entity.GisConfigRow;
import com.szholly.plug.arcgis.entity.GisConfigTable;
import com.szholly.utils.freemarker.directive.DirectiveUtils;
import com.szholly.utils.freemarker.directive.IDirective;
import com.szholly.utils.spring.SpringBeanFactory;
import com.szholly.utils.spring.springmvc.route.FunctionInfo;
import com.szholly.utils.util.StringUtils;
import com.szholly.data.common.util.TreeDataUtils;
import com.szholly.data.general.IQueryMap;
import com.szholly.data.general.ITable;
import com.szholly.data.general.ITableFactory;
import com.szholly.data.general.QueryMap;
import com.szholly.data.general.RowBase;

import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;

/**
 * 定位器
 */
@Component("directive_locator")
public class LocatorDirective implements TemplateDirectiveModel, IDirective {
	@Override
	public FunctionInfo getFunctionInfo() {
		String paraInfo = "tableName：数据字典表名 <br/>order：排序字段<br/>jbs：需要加载的级别"
				+ "调用示例：<br/>"
				+ "<@locator><br/>"
				+ "<#if data??> <br/>" + "<#list data as item><br/>"
				+ "<li>${item.C_ORGNAME}</li><br/>" + "</#list><br/>"
				+ "</#if><br/>" + "</@locator><br/>";

		FunctionInfo info = new FunctionInfo("treedata", 1, "表单",
				"获取树型下拉框的字典数据", paraInfo);
		return info;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public void execute(Environment env, Map params, TemplateModel[] model,
			TemplateDirectiveBody body) throws TemplateException, IOException {

		List<Map<String, Object>> result = null;
		GisConfigRow config = GisConfigTable.getSingleRef().getEntity(
				GisConfigRow.class, new QueryMap());
		if (config == null) {

		} else {
			String tableName = config.getLocatorTableName();
			String domainName = config.getLocatorDomainName();
			String order = config.getLocatorOrder();
			String jbs = config.getLocatorJbs();

			if (!StringUtils.IsNullOrSpace(tableName)) {
				ITableFactory tableFactory = (ITableFactory) SpringBeanFactory
						.getBean("TableFactory");
				ITable pTable = tableFactory.openTable(tableName);
				if(pTable!=null){
					IQueryMap queryMap = new QueryMap();
					queryMap.setAddCaptionField(true);
					
					if(!StringUtils.IsNullOrSpace(order)){
						order = "{"+order+"}";
						JSONObject orderJsonObject = JSONObject.fromObject(order);
						HashMap<String, Object> orderMap = (HashMap<String, Object>) JSONObject
								.toBean(orderJsonObject, HashMap.class);
						queryMap.setOrderByMap(orderMap);
					}

					// 没条件时，加上只加载指定级别数据
					if (!StringUtils.IsNullOrSpace(pTable.getLevelFieldName())
							&& !StringUtils.IsNullOrSpace(jbs)) {
						queryMap.getWhereMap().put(pTable.getLevelFieldName() + ":in",
								jbs);
					}
					
					if (!StringUtils.IsNullOrSpace(pTable.getDomainFieldName())
							&& !StringUtils.IsNullOrSpace(domainName)) {
						queryMap.getWhereMap().put(pTable.getDomainFieldName(),
								domainName);
					}
					
					List<RowBase> rows = pTable.getEntityList(RowBase.class, queryMap);
					result = TreeDataUtils.GetTreeData(rows, pTable.getIDFieldName(),
							pTable.getPIDFieldName(), pTable.getIsChildFieldName(),
							pTable.getCodeFieldName(), pTable.getCaptionFieldName());
				}
			}
		}

		Map<String, TemplateModel> paramWrap = new HashMap<String, TemplateModel>(
				params);
		paramWrap.put("data", DEFAULT_WRAPPER.wrap(result));
		if(config!=null){
			paramWrap.put("defname", DEFAULT_WRAPPER.wrap(config.getLocatorDefName()));
			String hot = config.getLocatorHot();
			if(!StringUtils.IsNullOrSpace(hot)){
				String[] hots = hot.split(" ");
				paramWrap.put("hots", DEFAULT_WRAPPER.wrap(hots));
			}
		} else {
			paramWrap.put("defname", DEFAULT_WRAPPER.wrap(""));
			String[] hots = new String[0];
			paramWrap.put("hots", DEFAULT_WRAPPER.wrap(hots));
		}
		
		Map<String, TemplateModel> origMap = DirectiveUtils
				.addParamsToVariable(env, paramWrap);
		body.render(env.getOut());
		DirectiveUtils.removeParamsFromVariable(env, paramWrap, origMap);
	}
}